/*
 * File Name：DrawBitmap.java
 * Copyright：Copyright 2008-2013 CiWong.Inc. All Rights Reserved.
 * Description： DrawBitmap.java
 * Modify By：jejun
 * Modify Date：2013-1-13
 * Modify Type：Add
 */
package com.ciwong.ciwongwrite.mode;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.Log;

import com.ciwong.ciwongwrite.R;
import com.ciwong.ciwongwrite.widget.DrawAction;


/**
 * <pre>
 * </pre>
 *
 * @author jejun
 * @version ciwong v.1.0 2013-1-13
 * @since ciwong v.1.0
 */
public class TrackBitmap extends TrackMouse
{

    public static class DrawBitmap extends DrawAction
    {
        private static final int CROP_EDGE = 20;

        Bitmap mBitmap;

        Bitmap cropBitmap;

        Bitmap primaryBitmap;

        ArrayList<CropImage> cropImages;

        Paint cropPaint;

        Context mContext;

        CropImage curCropImage;

        int editFlag;

        boolean isCrop;

        int w;

        int h;

        int cropW, cropH, cropBitmapW, cropBitmapH;

        Paint alphaPaint;

        public DrawBitmap(float x, float y, Bitmap mBitmap, Context context)
        {
            super();
            this.mBitmap = mBitmap;
            primaryBitmap = mBitmap;
            w = mBitmap.getWidth();
            h = mBitmap.getHeight();
            startX = x;
            startY = y;
            cropW = cropH = 0;
            mContext = context;
            editFlag = CropImage.FLAG_NONE;
            alphaPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            alphaPaint.setAlpha(0xaa);
        }

        @Override
        public void draw(Canvas canvas)
        {
            canvas.drawBitmap(mBitmap, startX, startY, isCrop ? alphaPaint
                    : null);
            if (isCrop)
            {
                canvas.drawBitmap(cropBitmap, startX - CROP_EDGE / 2 - cropW
                        / 2, startY - CROP_EDGE / 2 - cropH / 2, null);
            }
        }

        @Override
        public void move(float mx, float my)
        {
            startX = mx;
            startY = my;
        }

        /**
         * 在画布中移动图片
         */
        @Override
        public void moveTo(float mx, float my)
        {
            if (editFlag == CropImage.FLAG_NONE)
            {
                startX -= mx;
                startY -= my;
            }
            else
            {
                final int bw = mBitmap.getWidth();
                final int bh = mBitmap.getHeight();
                switch (editFlag)
                {
                    case CropImage.FLAG_LEFT:
                        mBitmap = Bitmap.createBitmap(valid(bw + (int) mx), bh,
                                Config.ARGB_8888);
                        startX -= mx;
                        break;
                    case CropImage.FLAG_TOP:
                        mBitmap = Bitmap.createBitmap(bw, valid(bh + (int) my),
                                Config.ARGB_8888);
                        startY -= my;
                        break;
                    case CropImage.FLAG_BOTTOM:
                        mBitmap = Bitmap.createBitmap(bw, valid(bh - (int) my),
                                Config.ARGB_8888);
                        break;
                    case CropImage.FLAG_RIGHT:
                        mBitmap = Bitmap.createBitmap(valid(bw - (int) mx), bh,
                                Config.ARGB_8888);
                        break;
                    case CropImage.FLAG_LEFT_TOP:
                        mBitmap = Bitmap.createBitmap(valid(bw + (int) mx),
                                valid(bh + (int) my), Config.ARGB_8888);
                        startX -= mx;
                        startY -= my;
                        break;
                    case CropImage.FLAG_RIGHT_TOP:
                        mBitmap = Bitmap.createBitmap(valid(bw - (int) mx),
                                valid(bh + (int) my), Config.ARGB_8888);
                        startY -= my;
                        break;
                    case CropImage.FLAG_LEFT_BOTTOM:
                        mBitmap = Bitmap.createBitmap(valid(bw + (int) mx),
                                valid(bh - (int) my), Config.ARGB_8888);
                        startX -= mx;
                        break;
                    case CropImage.FLAG_RIGHT_BOTTOM:
                        mBitmap = Bitmap.createBitmap(valid(bw - (int) mx),
                                valid(bh - (int) my), Config.ARGB_8888);
                        break;
                    default:
                        break;
                }
                final Canvas mCanvas = new Canvas(mBitmap);
                Rect dst = new Rect(0, 0, mBitmap.getWidth(),
                        mBitmap.getHeight());
                mCanvas.drawBitmap(primaryBitmap, null, dst, null);
                createCropBitmap();
            }
        }

        /**
         * 验证图片的宽高不能小于指定值
         *
         * @param num
         *            宽、高
         * @return 正确的宽、高
         */
        private int valid(int num)
        {
            return num > 5 ? num : 5;
        }

        /**
         * 使图片放大，说明该图片已被选中
         */
        @Override
        public void large()
        {
            if (cropImages == null)
            {
                cropImages = new ArrayList<CropImage>();
                cropPaint = new Paint();
                cropPaint.setAntiAlias(true);
                cropPaint.setStrokeWidth(5);
                cropPaint.setColor(0x88B8860B);
                cropPaint.setStyle(Style.STROKE);
                int normalResId;
                int pressResId;
                if (mContext != null)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        final CropImage image = new CropImage();
                        if (i % 2 == 0)
                        {
                            normalResId = R.mipmap.rotate_horizontalrotate_a;
                            pressResId = R.mipmap.rotate_horizontalrotate_c;
                        }
                        else
                        {
                            normalResId = R.mipmap.rotate_verticalrotate_a;
                            pressResId = R.mipmap.rotate_verticalrotate_c;
                        }
                        image.bitmapNormal = BitmapFactory.decodeResource(
                                mContext.getResources(), normalResId);
                        image.bitmapPress = BitmapFactory.decodeResource(
                                mContext.getResources(), pressResId);
                        cropW = image.bitmapNormal.getWidth();
                        cropH = image.bitmapNormal.getHeight();
                        cropImages.add(image);
                    }
                    Matrix m = new Matrix();
                    m.setRotate(45);
                    final Bitmap tempNormal = cropImages.get(0).bitmapNormal;
                    final Bitmap tempPress = cropImages.get(0).bitmapPress;
                    final int w = tempNormal.getWidth();
                    final int h = tempNormal.getHeight();
                    Bitmap angles1 = Bitmap.createBitmap(tempNormal, 0, 0, w,
                            h, m, true);
                    Bitmap angles2 = Bitmap.createBitmap(tempPress, 0, 0, w, h,
                            m, true);
                    m.setRotate(-45);
                    Bitmap angles3 = Bitmap.createBitmap(tempNormal, 0, 0, w,
                            h, m, true);
                    Bitmap angles4 = Bitmap.createBitmap(tempPress, 0, 0, w, h,
                            m, true);
                    for (int i = 0; i < 4; i++)
                    {
                        final CropImage image = new CropImage();
                        if (i % 2 == 0)
                        {
                            image.bitmapNormal = angles1;
                            image.bitmapPress = angles2;
                        }
                        else
                        {
                            image.bitmapNormal = angles3;
                            image.bitmapPress = angles4;
                        }
                        cropImages.add(image);
                    }
                }
            }
            createCropBitmap();
            isCrop = true;
        }

        public void createCropBitmap()
        {
            w = mBitmap.getWidth();
            h = mBitmap.getHeight();
            cropBitmap = null;
            cropBitmap = Bitmap.createBitmap(w + CROP_EDGE + cropW, h
                    + CROP_EDGE + cropH, Config.ARGB_8888);
            cropBitmapW = cropBitmap.getWidth();
            cropBitmapH = cropBitmap.getHeight();
            Canvas mCanvas = new Canvas(cropBitmap);
            Rect r = new Rect(cropW / 2, cropH / 2, cropBitmap.getWidth()
                    - cropW / 2, cropBitmap.getHeight() - cropH / 2);
            mCanvas.drawRect(r, cropPaint);
            if (cropImages != null && cropImages.size() > 0)
            {
                final int cw = cropBitmap.getWidth();
                final int ch = cropBitmap.getHeight();
                CropImage ci = cropImages.get(0);
                ci.flag = CropImage.FLAG_LEFT;
                ci.xy[0] = 0;
                ci.xy[1] = (ch - cropH) / 2;
                ci.xy[2] = ci.bitmapNormal.getWidth();
                ci.xy[3] = ci.bitmapNormal.getHeight() + (ch - cropH) / 2;
                mCanvas.drawBitmap(getCropBitmap(ci), ci.xy[0], ci.xy[1], null);
                ci = cropImages.get(1);
                ci.flag = CropImage.FLAG_TOP;
                ci.xy[0] = (cw - cropW) / 2;
                ci.xy[1] = 0;
                ci.xy[2] = ci.bitmapNormal.getWidth() + ci.xy[0];
                ci.xy[3] = ci.bitmapNormal.getHeight();
                mCanvas.drawBitmap(getCropBitmap(ci), ci.xy[0], ci.xy[1], null);
                ci = cropImages.get(2);
                ci.flag = CropImage.FLAG_RIGHT;
                ci.xy[0] = cw - cropW;
                ci.xy[1] = (ch - cropH) / 2;
                ci.xy[2] = ci.bitmapNormal.getWidth() + ci.xy[0];
                ci.xy[3] = ci.bitmapNormal.getHeight() + ci.xy[1];
                mCanvas.drawBitmap(getCropBitmap(ci), ci.xy[0], ci.xy[1], null);
                ci = cropImages.get(3);
                ci.flag = CropImage.FLAG_BOTTOM;
                ci.xy[0] = (cw - cropH) / 2;
                ci.xy[1] = ch - cropH;
                ci.xy[2] = ci.bitmapNormal.getWidth() + ci.xy[0];
                ci.xy[3] = ci.bitmapNormal.getHeight() + ci.xy[1];
                mCanvas.drawBitmap(getCropBitmap(ci), ci.xy[0], ci.xy[1], null);
                ci = cropImages.get(4);
                ci.flag = CropImage.FLAG_LEFT_TOP;
                ci.xy[0] = -cropW / 4;
                ci.xy[1] = -cropH / 4;
                ci.xy[2] = ci.bitmapNormal.getWidth() + ci.xy[0];
                ci.xy[3] = ci.bitmapNormal.getHeight() + ci.xy[1];
                mCanvas.drawBitmap(getCropBitmap(ci), ci.xy[0], ci.xy[1], null);
                ci = cropImages.get(5);
                ci.flag = CropImage.FLAG_RIGHT_TOP;
                ci.xy[0] = cw - cropW * 5 / 4;
                ci.xy[1] = -cropH / 4;
                ci.xy[2] = ci.bitmapNormal.getWidth() + ci.xy[0];
                ci.xy[3] = ci.bitmapNormal.getHeight() + ci.xy[1];
                mCanvas.drawBitmap(getCropBitmap(ci), ci.xy[0], ci.xy[1], null);
                ci = cropImages.get(6);
                ci.flag = CropImage.FLAG_RIGHT_BOTTOM;
                ci.xy[0] = cw - cropW * 5 / 4;
                ci.xy[1] = ch - cropH * 5 / 4;
                ci.xy[2] = ci.bitmapNormal.getWidth() + ci.xy[0];
                ci.xy[3] = ci.bitmapNormal.getHeight() + ci.xy[1];
                mCanvas.drawBitmap(getCropBitmap(ci), ci.xy[0], ci.xy[1], null);
                ci = cropImages.get(7);
                ci.flag = CropImage.FLAG_LEFT_BOTTOM;
                ci.xy[0] = -cropW / 4;
                ci.xy[1] = ch - cropH * 5 / 4;
                ci.xy[2] = ci.bitmapNormal.getWidth() + ci.xy[0];
                ci.xy[3] = ci.bitmapNormal.getHeight() + ci.xy[1];
                mCanvas.drawBitmap(getCropBitmap(ci), ci.xy[0], ci.xy[1], null);
            }
        }

        /**
         * 获取CropImage中的图片(正常的或是点击的图片)
         *
         * @param ci
         *            CropImage
         * @return Bitmap
         */
        private Bitmap getCropBitmap(CropImage ci)
        {
            return (ci.isEdit ? ci.bitmapPress : ci.bitmapNormal);
        }

        @Override
        public void reset()
        {
            isCrop = false;
        }

        public void resetEdit()
        {
            if (curCropImage != null)
            {
                curCropImage.isEdit = false;
                createCropBitmap();
            }
        }

        /**
         * 识别是否点击了边框按扭
         *
         * @param x
         *            画布的X坐标(注：画布不是本对象中的画布)
         * @param y
         *            画布的Y坐标(注：画布不是本对象中的画布)
         * @return true表示手指触摸的是边框上的按钮
         */
        public boolean edit(float x, float y)
        {
            int len = cropImages.size();
            boolean retVal = false;
            editFlag = CropImage.FLAG_NONE;
            final float innerX = x - (startX - CROP_EDGE / 2 - cropW / 2);
            final float innerY = y - (startY - CROP_EDGE / 2 - cropH / 2);
            for (int i = 0; i < len; i++)
            {
                if (innerX > 0 && innerY > 0)
                {
                    final CropImage ci = cropImages.get(i);
                    if (innerX > ci.xy[0] && innerY > ci.xy[1]
                            && innerX < ci.xy[2] && innerY < ci.xy[3])
                    {
                        editFlag = ci.flag;
                        ci.isEdit = true;
                        curCropImage = ci;
                        retVal = true;
                    }
                    else
                    {
                        ci.isEdit = false;
                    }
                }
            }
            Log.i("debug", "editFlag:" + retVal);
            return retVal;
        }

        /**
         * 判断点击区域是否在此图片内
         */
        @Override
        public boolean isInArea(float x, float y)
        {
            return x > startX && y > startY && x < (startX + w)
                    && y < (startY + h);
        }

        static class CropImage
        {
            public static final int FLAG_NONE = -1;

            public static final int FLAG_LEFT = 0;

            public static final int FLAG_TOP = 1;

            public static final int FLAG_RIGHT = 2;

            public static final int FLAG_BOTTOM = 3;

            public static final int FLAG_LEFT_TOP = 4;

            public static final int FLAG_RIGHT_TOP = 5;

            public static final int FLAG_LEFT_BOTTOM = 6;

            public static final int FLAG_RIGHT_BOTTOM = 7;

            public Bitmap bitmapNormal;

            public Bitmap bitmapPress;

            public float[] xy = new float[4];

            public int flag;

            public boolean isEdit;
        }
    }
}
